package DAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JOptionPane;

import modelo.Funcionario;
import modelo.Localizacao;
import connection.ConnectionManager;
/**
 * 
 * @author Fernando
 * classe com todo os metodos do crud para funcionario
 */

public class FuncionarioDAOImp implements FuncionarioDAO {

	/**
         * crie os metodos para alterar os funcionarios no banco de dados passando
         * esses metodos abaixo
         */
         /**
          * Metodo para inserir funcionarios do banco de dados
          */
        private final String INSERT = "INSERT INTO Funcionario(ctps, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento,telefone) VALUES (?,?,?,?,?,?,?,?,?,?)";
	/**
         * metodo para alterar funcionarios no banco de dados
         */
        private final String UPDATE = "UPDATE Funcionario SET ctps=?, id_localizacao=?, sobrenome=?, cpf=?, email=?, nome=?, senha=?, sexo=?, nascimento=?, telefone= ? WHERE id_funcionario = ?";
	/**
         * metodo para deletar funcionarios no banco de dados
         */
        private final String DELETE = "DELETE from Funcionario WHERE id_funcionario = ?";
	/**
         * metodo para mostrar todos os funcionarios no banco de dados
         */
        private final String ALL = "SELECT id_funcionario, ctps, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento,telefone FROM Funcionario";
	/**
         * metodo para buscar funcionarios usando LIKE no nome  
         */
        private final String LIKE = "SELECT id_funcionario,ctps, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento,telefone FROM Funcionario where nome like ?";
	/**
         * metodo para buscar funcionarios por identificador no banco de dados
         */
        private final String ID = "SELECT id_funcionario,nome,ctps, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento,telefone FROM Funcionario where id_Funcionario = ?";
	/**
         * metodo para buscar funcionarios pelo cpf no banco de dados
         */
        private final String CPF = "SELECT id_funcionario,ctps,nome,sobrenome,senha ,cpf,sexo,nascimento,email,telefone,id_localizacao,telefone FROM Funcionario where cpf = ?";
	/**
         * metodo para buscar funcionario por email para efetuar login
         */
        private final String EMAIL = "SELECT id_funcionario,nome,ctps, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento,telefone FROM Funcionario where email like ?";

        
        /**
         * variaveis de conex@@o
         */
	private ConnectionManager connectionManager;
	private static Connection connection;

	FuncionarioDAOImp() {
		this.openConnection();
	}

	public boolean isConnectionClose() {
		try {
			return connection.isClosed();
		} catch (SQLException ex) {
			return false;
		}
	}

	@Override
        /**
         * metodo para cadastrar um funcionario
         */
	public Funcionario salvar(Funcionario e) {
		PreparedStatement ps = null;
		try {
			/**
                         * crie uma instancia de PreparedStatement
			 * passe para ela a instrucao para realizar alteracoes em uma
			 * registro do banco
                         */
			ps = connection.prepareStatement(INSERT);

			ps.setObject(1, e.getCtps());
			ps.setObject(2, e.getLocalizacao().getIdLocalizacao());
			ps.setObject(3, e.getSobrenome());
			ps.setObject(4, e.getCpf());
			ps.setObject(5, e.getEmail());
			ps.setObject(6, e.getNome());
			ps.setObject(7, e.getSenha());
			ps.setObject(8, e.isSexo());
			ps.setObject(9, e.getNascimento());
			ps.setObject(10, e.getTelefone());
			
			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(FuncionarioDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return e;

	}

	@Override
        /**
         * metodo para alterar funcionarios
         */
	public void alterar(Funcionario e) {
		PreparedStatement ps = null;
		try {
			/**
                         * crie uma instancia de PreparedStatement
			 * passe para ela a instrucao para realizar alteracoes em uma
			 * registro do banco
                         */
			ps = connection.prepareStatement(UPDATE);

			ps.setObject(1, e.getCtps());
			ps.setObject(2, e.getLocalizacao().getIdLocalizacao());
			ps.setObject(3, e.getSobrenome());
			ps.setObject(4, e.getCpf());
			ps.setObject(5, e.getEmail());
			ps.setObject(6, e.getNome());
			ps.setObject(7, e.getSenha());
			ps.setObject(8, e.isSexo());
			ps.setObject(9, e.getNascimento());
			ps.setObject(10, e.getTelefone());
			ps.setObject(11, e.getId());

			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(FuncionarioDAOImp.class.getName()).log(
					Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}

	}

	@Override
        /**
         * metodo para deletar funcionarios
         */
	public void deletar(Funcionario e) {
		try {
			PreparedStatement ps = null;
			ps = connection.prepareStatement(DELETE);
			/**
                         * passe para o PreparedStatement o valor do id que deve ser
			 * excluido do banco de dados
                         */ 
			ps.setObject(1, e.getId());

			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(FuncionarioDAOImp.class.getName()).log(
					Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}

	}

	@Override
        /**
         * metodo  para listar dos os funcionarios
         */
	public List<Funcionario> findAll() {
		List<Funcionario> funcionarios = new ArrayList<Funcionario>();
		LocalizacaoDAO local =  DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(ALL);

			/**
                         * Obtenha uma instancia de resultset
                         * passando parametro ALL
                         */
			rs = ps.executeQuery();

			while (rs.next()) {
				Funcionario funcionario = new Funcionario();
				funcionario.setId(rs.getInt("id_funcionario"));
				funcionario.setCtps(rs.getString("ctps"));
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				funcionario.setLocalizacao(locais.get(0));
				funcionario.setSobrenome(rs.getString(4));
				funcionario.setCpf(rs.getString(5));
				funcionario.setEmail(rs.getString(6));
				funcionario.setNome(rs.getString(7));
				funcionario.setSenha(rs.getString(8));
				funcionario.setSexo(rs.getBoolean(9));
				funcionario.setNascimento(rs.getDate(10));
				funcionario.setTelefone(rs.getString("telefone"));
				funcionarios.add(funcionario);
				/** 
                                 * crie uma instancia de funcionario com os dados
				 * obtidos do banco e adicione a lista de funcionario
                                */        

			}

		} catch (SQLException ex) {
			Logger.getLogger(FuncionarioDAOImp.class.getName()).log(
					Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return funcionarios;
	}

	@Override
          /**
	 * testando se a conexao com o banco esta fechada
	 */
	public void openConnection() {
		if (connectionManager == null) {
			connectionManager = ConnectionManager.getInstance();
		}

		if (connection == null) {
			connection = connectionManager.getConnection();
		}

		if (isConnectionClose()) {
			connection = connectionManager.getConnection();
		}

	}

	@Override
	public void closeConnection() {
		if (connection != null && connectionManager != null) {
			if (!this.isConnectionClose()) {
				connectionManager.closeConnection(connection);
			}
		}

	}

	@Override
        /**
         * buscando funcionario por nome
         */
	public List<Funcionario> buscaFuncionarioPorNome(Funcionario funcionario) {
		List<Funcionario> funcionarios = new ArrayList<Funcionario>();
		LocalizacaoDAO local =  DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(LIKE);
			/**
                         * informe o parmetro para instrucao like
                         */ 
			ps.setObject(1, funcionario.getNome());

			rs = ps.executeQuery();

			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs
						.getInt("id_localizacao"));
				funcionarios.add(new Funcionario(rs.getInt("id_funcionario"),
						rs.getString("ctps"), rs.getString("nome"), rs
								.getString("sobrenome"), rs.getString("senha"),
						rs.getString("cpf"), rs.getBoolean("sexo"), rs
								.getDate("nascimento"), rs.getString("email"),
						locais.get(0), rs.getString("telefone")));
			}
		} catch (SQLException ex) {
			Logger.getLogger(FuncionarioDAOImp.class.getName()).log(
					Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return funcionarios;
	}

	@Override
        /**
         * buscando funcionario por identificador
         */
	public List<Funcionario> buscaFuncionarioPorId(Funcionario funcionario) {
		List<Funcionario> funcionarios = new ArrayList<Funcionario>();
		LocalizacaoDAO local =  DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(ID);
			/**
                         * informe o parmetro para instrucao ID
                         */ 
			ps.setObject(1, funcionario.getId());

			rs = ps.executeQuery();

			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				funcionarios.add(new Funcionario(rs.getInt("id_funcionario"),
						rs.getString("ctps"),
						rs.getString("nome"),
						rs.getString("sobrenome"),
						rs.getString("senha"),
						rs.getString("cpf"), 
						rs.getBoolean("sexo"), 
						rs.getDate("nascimento"),
						rs.getString("email"),
						locais.get(0), 
						rs.getString("telefone")));
			}
		} catch (SQLException ex) {
			Logger.getLogger(FuncionarioDAOImp.class.getName()).log(
					Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return funcionarios;
	}

	@Override
        /**
         * buscando funcionario por cpf
         */
	public List<Funcionario> buscaFuncionarioPorCpf(Funcionario funcionario) {
		List<Funcionario> funcionarios = new ArrayList<Funcionario>();
		LocalizacaoDAO local =  DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(CPF);
			/**
                         * informe o parmetro para instrucao cpf
                         */
                        
			ps.setObject(1, funcionario.getCpf());
			
			rs = ps.executeQuery();
			
			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				
				funcionarios.add(new Funcionario(
						rs.getInt("id_funcionario"),
						rs.getString("ctps"),
						rs.getString("nome"),
						rs.getString("sobrenome"),
						rs.getString("senha"),
						rs.getString("cpf"),
						rs.getBoolean("sexo"),
						rs.getDate("nascimento"),
						rs.getString("email"),
						locais.get(0),
						rs.getString("telefone")));
	
			}
			
		} catch (SQLException ex) {
			Logger.getLogger(FuncionarioDAOImp.class.getName()).log(Level.SEVERE,null, ex);
			JOptionPane.showMessageDialog(null,funcionarios.get(0).getCtps());
			
		} finally {
			this.closeConnection();
		}
		
		
		return funcionarios;
	}

	@Override
	public List<Funcionario> buscaFuncionarioPorEmail(Funcionario funcionario) {
		List<Funcionario> funcionarios = new ArrayList<Funcionario>();
		LocalizacaoDAO local =  DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(EMAIL);
			// 6 informe o parmetro para instrucao like
			ps.setObject(1, funcionario.getEmail());

			rs = ps.executeQuery();

			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs
						.getInt("id_localizacao"));
				funcionarios.add(new Funcionario(rs.getInt("id_funcionario"),
						rs.getString("ctps"), rs.getString("nome"), rs
								.getString("sobrenome"), rs.getString("senha"),
						rs.getString("cpf"), rs.getBoolean("sexo"), rs
								.getDate("nascimento"), rs.getString("email"),
						locais.get(0), rs.getString("telefone")));
			}
		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}
		return funcionarios;
	}

}
